<template>
  <a-drawer
    :title="title"
    :maskClosable="true"
    :visible="visible"
    :destroyOnClose="true"
    :width="500"
    :body-style="{ paddingBottom: '80px' }"
    @close="closeModal"
  >
    <a-spin :spinning="spinning">
      <a-alert
        message="未设置计算规则的费用类型，应收默认不含调整和滞纳金，按照“按自然月-合同条款分摊”计算，实收默认不含结转，按照“按应收金额分摊”计算。"
        type="warning"
        class="mb-20"
      />
      <a-form layout="vertical" ref="formRef" :model="modelRef">
        <a-row :gutter="[12, 0]" :wrap="true">
          <a-col :span="24">
            <div class="mark-title mb-10">基本信息</div>
          </a-col>
          <a-col :span="24">
            <a-form-item name="rule_name" label="收入规则名称" :rules="rulesRef.rule_name">
              <a-input v-model:value="modelRef.rule_name" placeholder="请输入收入规则名称" />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item name="org_branch_id" label="所属公司" :rules="rulesRef.org_branch_id">
              <a-select
                v-model:value="modelRef.org_branch_id"
                placeholder="请选择所属公司"
                :options="companyList"
                allowClear
              ></a-select>
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item name="remark" label="备注">
              <a-textarea
                v-model:value="modelRef.remark"
                placeholder="请输入备注"
                :rows="3"
              />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-row type="flex" justify="space-between" align="middle">
              <a-col :flex="1">
                <div class="mark-title">规则信息</div>
              </a-col>
              <a-col>
                <a-button size="small" style="font-size: 12px" type="primary" ghost @click="addRule">+收入确认规则</a-button>
              </a-col>
            </a-row>
          </a-col>
          <a-col :span="24" v-for="(item, index) in modelRef.rule_info" :key="index">
            <div class="line-box">
              <div class="line-left"></div>
              <div class="line-content">{{`规则${index + 1}`}}</div>
              <div class="line-right">
                <a-popconfirm v-if="index > 0" placement="topRight" class="line-right-del" title="是否确定要删除?" @confirm="deleteRule(index)">
                  <a-button
                    type="link"
                    danger
                  >
                    <template #icon>
                      <DeleteOutlined/>
                    </template>
                  </a-button>
                </a-popconfirm>
              </div>
            </div>
            <a-row :gutter="[12, 0]" :wrap="true">
              <a-col :span="12">
                <a-form-item
                  :name="['rule_info', index, 'cost_type']"
                  label="费用类型"
                  :rules="{
                required: true,
                message: '费用类型必填',
                }"
                >
                  <a-cascader
                    v-model:value="item.cost_type"
                    :options="costTypeList"
                    :load-data="getCostTypeSub"
                    placeholder="请选择"
                    dropdownClassName="fee-type-cascader-custom"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  :name="['rule_info', index, 'receivables_range']"
                  label="应收计算范围"
                  :rules="{
                required: true,
                message: '应收计算范围必填',
                }"
                >
                  <a-select
                    v-model:value="item.receivables_range"
                    placeholder="请选择应收计算范围"
                    :options="incomeScopeOptions"
                    allowClear
                  ></a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  :name="['rule_info', index, 'receivables_rule']"
                  :rules="{
                required: true,
                message: '应收计算规则必填',
                }"
                >
                  <template #label>
                    <span>应收计算规则</span>
                    <text-tip
                      :tips="[
                        '按自然月分摊&按合同条款分摊：默认减免金额在当期内分摊，计算方式为：租金明细当期金额/当期天数/（1+税率）*在租的自然月天数，免租期和装修期为0',
                        '按自然月分摊&按合同总价分摊：此时减免金额、免租期、装修期都进行了分摊，计算方式为：合同总金额/合同总天数/（1+税率）*在租的自然月天数',
                        '按平均月分摊&按合同条款分摊：默认免租期和装修期不分摊，计算整自然月的摊销值：年金额/12/（1+税率）',
                        '按平均月分摊&按合同总价分摊：合同总金额/合同总天数*年天数/12/（1+税率），此时减免金额、免租期、装修期都进行了分摊',
                        '按合同条款起始日分摊：租金明细当期金额确认收入在当期第一个月份',
                        ]"
                    />
                  </template>
                  <a-select
                    v-model:value="item.receivables_rule"
                    placeholder="请选择应收计算规则"
                    :options="incomeRuleOptions"
                    allowClear
                  ></a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12" v-if="item.receivables_rule == 3">
                <a-form-item
                  :name="['rule_info', index, 'reduction_amount_type']"
                  label="减免金额分摊类型"
                  :rules="{
                required: true,
                message: '减免金额分摊类型必填',
                }"
                >
                  <a-select
                    v-model:value="item.reduction_amount_type"
                    placeholder="请选择减免金额分摊类型"
                    :options="reducedContributionTypeOptions"
                    allowClear
                  ></a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  :name="['rule_info', index, 'actual_range']"
                  label="实收计算范围"
                  :rules="{
                required: true,
                message: '实收计算范围必填',
                }"
                >
                  <a-select
                    v-model:value="item.actual_range"
                    placeholder="请选择实收计算范围"
                    :options="receiveScopeOptions"
                    allowClear
                  ></a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  :name="['rule_info', index, 'actual_rule']"
                  label="实收计算规则"
                  :rules="{
                required: true,
                message: '实收计算规则必填',
                }"
                >
                  <a-select
                    v-model:value="item.actual_rule"
                    placeholder="请选择实收计算规则"
                    :options="receiveRuleOptions"
                    allowClear
                  ></a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item
                  :name="['rule_info', index, 'default_income_confirm']"
                  label="确认收入默认值"
                  :rules="{
                required: true,
                message: '确认收入默认值必填',
                }"
                >
                  <a-select
                    v-model:value="item.default_income_confirm"
                    placeholder="请选择确认收入默认值"
                    :options="confirmDefaultOptions"
                    allowClear
                  ></a-select>
                </a-form-item>
              </a-col>
              <a-col :span="12" v-if="item.actual_rule == 1">
                <a-form-item
                  :name="['rule_info', index, 'actual_payment_month']"
                  :rules="{
                required: true,
                message: '实收确认月份必填',
                }"
                >
                  <template #label>
                    <span>实收确认月份</span>
                    <text-tip
                      :tips="['按入账月份往后确认，摊销月份不早于账单开始月份']"
                    />
                  </template>
                  <a-month-picker
                    class="w-100p"
                    v-model:value="item.actual_payment_month"
                    placeholder="请选择实收确认月份"
                    :format="monthFormat"
                    :valueFormat="monthFormat"
                    :allowClear="true"
                  />
                </a-form-item>
              </a-col>
            </a-row>
          </a-col>
        </a-row>
      </a-form>
    </a-spin>
    <div class="drawer-footer">
      <a-button class="mr-10" @click.prevent="closeModal">取消</a-button>
      <a-button type="primary" :disabled="spinning" :loading="submitLoading" @click.prevent="onSubmit">保存</a-button>
    </div>
  </a-drawer>
</template>

<script>
import {computed, defineComponent, reactive, ref, toRaw, toRefs, watch, watchEffect} from "vue";
import { Form, message } from "ant-design-vue";
import _ from "lodash";
import request from "@/common/utils/request";
import {DeleteOutlined, EditOutlined, PlusOutlined} from "@ant-design/icons-vue";
import { TextTip } from "bl-common-vue3";
import store from "@/store";
const defaultData = {
  cost_type: undefined, // 费用类型
  receivables_range: undefined, // 应收计算范围
  receivables_rule: undefined, // 应收计算规则
  actual_range: undefined, // 实收计算范围
  actual_rule: undefined, // 实收计算规则
  default_income_confirm: undefined, // 确认收入默认值
  reduction_amount_type: undefined, // 减免分摊类型
  actual_payment_month: undefined, // 实收确认月份
};
const monthFormat = "YYYY-MM";

export default defineComponent({
  name: "EditConfirmRule",
  components: {DeleteOutlined, EditOutlined, PlusOutlined, TextTip },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    id: {
      type: [Number, String],
      default: 0,
    },
  },
  setup(props, context) {

    const title = computed(() => (props.id ? "编辑" : "新建") + "收入确认规则");
    const formRef = ref();

    const modelRef = reactive({
      rule_name: '',
      org_branch_id: undefined,
      remark: '',
      rule_info: [_.cloneDeep(defaultData)],
    });

    const state = reactive({
      companyList: [], // 公司下拉
      costTypeList: [], // 费用类型下拉
      submitLoading: false,
      spinning: false,
      detail: {},
    });
    const closeModal = () => {
      context.emit("handleClose");
    };



    const rulesRef = reactive({
      rule_name: [{ required: true, message: "收入规则名称必填"}],
      org_branch_id: [{ required: true, message: "所属公司必填" }],
    });

    const getCostTypeSub = (selectedOptions) => {
      const targetOption = selectedOptions[selectedOptions.length - 1];
      if (targetOption?.children?.length) return;
      targetOption.loading = true;
      request
        .get("/org", "/bill/costList", {
          page: 1,
          limit: 9999,
          category_id: targetOption.value,
          status: 1,
          is_bond: 0,
        })
        .then((res) => {
          if (res.list) {
            targetOption.loading = false;
            targetOption.children = res.list.map((item) => ({
              label: item.name,
              value: item.cost_type,
              isLeaf: true,
            }));
            state.costTypeList = [...state.costTypeList];
          }
        });
    };

    const addRule = () => {
      modelRef.rule_info.push(_.cloneDeep(defaultData));
    };

    const deleteRule = (index) => {
      modelRef.rule_info.splice(index, 1);
    };

    const onSubmit = () => {
      formRef.value
        .validate()
        .then(() => {
          state.submitLoading = true;
          let params = _.cloneDeep(modelRef);
          if (params.rule_info.length) {
            params.rule_info.forEach((item) => {
              if (item.cost_type?.length > 1) {
                item.cost_type = item.cost_type[1];
              } else {
                item.cost_type = undefined;
              }
              if (item.receivables_rule != 3) {
                item.reduction_amount_type = undefined;
              }
              if (item.actual_rule != 1) {
                item.actual_payment_month = undefined;
              }
            });
          }
          let requestUrl = props.id ? "/incomeConfirmRule/editIncomeConfirmRule" : "/incomeConfirmRule/addIncomeConfirmRule";
          if (props.id) {
            params.id = props.id;
          }
          request.post("/org", requestUrl, params).then((res) => {
            state.submitLoading = false;
            message.success(res.msg || "保存成功");
            context.emit("handleSuccess");
          }).catch(() => {
            state.submitLoading = false;
          });
        })
        .catch(error => {

        });
    };

    const getCostCategory = () => {
      return new Promise((resolve, reject) => {
        request.get("/org", "/bill/cost/categoryList", {is_bond: 0}).then((res) => {
          if (res.list) {
            state.costTypeList = res.list.map((item) => ({
              label: item.name,
              value: item.id,
              isLeaf: false,
            }));
          }
          resolve();
        });
      });

    };

    const getOrgBranchList = () => {
      let params = {};
      if (state.detail?.org_branch_id || state.detail?.org_branch_id == 0) {
        params.org_branch_id = state.detail.org_branch_id
      }
      request.get("/org", "/incomeConfirmRule/branchList", params).then((res) => {
        state.companyList = (res?.list || []).map((item) => ({
          label: item.company,
          value: item.id,
        }));
      });
    };

    const getCostChildren = async (ids) => {
      for (let index in state.costTypeList) {
        let item = state.costTypeList[index];
        let haveId = ids.find((v) => v == item.value);
        if (haveId && !item.children?.length) {
          await request
            .get("/org", "/bill/costList", {
              page: 1,
              limit: 9999,
              category_id: haveId,
              status: 1,
              is_bond: 0,
            })
            .then((res) => {
              if (res.list) {
                item.children = res.list.map((item) => ({
                  label: item.name,
                  value: item.cost_type,
                  isLeaf: true,
                }));
              }
            });
        }
      }
    };

    const setModelRef = (info) => {
      for (let key in info) {
        modelRef[key] = info[key];
      }
    };

    const getDetail = () => {
      state.spinning = true;
      request.get("/org", "/incomeConfirmRule/incomeConfirmRuleDetail", {id: props.id}).then(async (res) => {
        let detail = res?.detail || {};
        state.detail = detail;
        getOrgBranchList();
        let ruleList = detail?.confirm_rule || [];
        let ruleListParentIds = ruleList.map((v) => v.parent_id);
        const uniqueArray = [...new Set(ruleListParentIds)];
        await getCostChildren(uniqueArray);
        let ruleInfo = _.cloneDeep(ruleList).map((item) => {
          item.cost_type = [item.parent_id, item.cost_type];
          delete item.parent_id;
          return {
            ...item
          }
        })
        setModelRef({
          org_branch_id: detail?.org_branch_id,
          remark: detail?.remark,
          rule_name: detail?.rule_name,
          rule_info: ruleInfo,
        })
        state.spinning = false;
      }).catch(() => {
        state.spinning = false;
      });
    };

    const init = () => {
      getCostCategory().then(() => {
        if (props.id) {
          // 编辑 拿详情
          getDetail();
        } else {
          getOrgBranchList();
        }
      });
    };

    const resetForm = () => {
      formRef.value.resetFields();
      modelRef.rule_info = [_.cloneDeep(defaultData)];
    };


    watch(
      () => props.visible,
      (val) => {
        if (val) {
          init();
        } else {
          resetForm();
          state.submitLoading = false;
          state.companyList = [];
          state.costTypeList = [];
          state.spinning = false;
          state.detail = {};
        }
      }
    );

    /* 实现不可重复添加相同费用类型 */
    const getDisabledCost = () => {
      const allCost = modelRef.rule_info.filter(item => item.cost_type)?.map(item => item.cost_type);
      let costObj = {}; // id: list
      allCost.forEach((item) => {
        if (item?.length > 1) {
          let categoryId = item[0];
          let cost_type = item[1];
          if (costObj[categoryId]) {
            costObj[categoryId].push(cost_type);
          } else {
            costObj[categoryId] = [cost_type];
          }
        }
      })
      state.costTypeList.forEach((item) => {
        if (costObj[item.value]) {
          // 子项有选择的
          (item?.children || []).forEach((child) => {
            if (costObj[item.value].includes(child.value)) {
              child.disabled = true;
            } else {
              child.disabled = false;
            }
          })
        } else {
          // 子项没选择的
          (item?.children || []).forEach((child) => {
            child.disabled = false;
          })
        }
      })
    };

    watchEffect(() => {
      getDisabledCost();
    })


    return {
      ...toRefs(state),
      title,
      modelRef,
      formRef,
      rulesRef,
      incomeScopeOptions,
      incomeRuleOptions,
      reducedContributionTypeOptions,
      receiveScopeOptions,
      receiveRuleOptions,
      confirmDefaultOptions,
      monthFormat,
      closeModal,
      onSubmit,
      getCostTypeSub,
      addRule,
      deleteRule,
    };
  },
});

const incomeScopeOptions = [
  {
    label: '应收（不含调整和滞纳金）',
    value: '1',
  },
  {
    label: '应收（含调整不含滞纳金）',
    value: '2',
  },
  {
    label: '应收（含滞纳金不含调整）',
    value: '3',
  },
  {
    label: '应收（含滞纳金和调整）',
    value: '4',
  }
];
const incomeRuleOptions = [
  {
    label: '按自然月-合同条款分摊',
    value: '1',
  },
  {
    label: '按自然月-合同总价分摊',
    value: '2',
  },
  {
    label: '按平均月-合同条款分摊',
    value: '3',
  },
  {
    label: '按平均月-合同总价分摊',
    value: '4',
  },
  {
    label: '按合同条款起始日分摊',
    value: '5',
  },
  {
    label: '按自然月-账单总价分摊',
    value: '6',
  },
  {
    label: '按平均月-账单总价分摊',
    value: '7',
  },
];
const reducedContributionTypeOptions = [
  {
    label: '不分摊',
    value: '1',
  },
  {
    label: '当期内分摊',
    value: '2',
  },
];
const receiveScopeOptions = [
  {
    label: '实收（不含结转）',
    value: '1',
  },
  {
    label: '实收（含结转）',
    value: '2',
  },
];
const receiveRuleOptions = [
  // {
  //   label: '按应收计算规则分摊',
  //   value: '1',
  // },
  {
    label: '按应收金额分摊',
    value: '2',
  },
  {
    label: '按入账日期分摊',
    value: '3',
  },
];
const confirmDefaultOptions = [
  {
    label: '应收（含税）',
    value: '1',
  },
  {
    label: '应收（不含税）',
    value: '2',
  },
  {
    label: '实收（含税）',
    value: '3',
  },
  {
    label: '实收（不含税）',
    value: '4',
  },
]
</script>

<style lang="less" scoped>
.mark-title {
  height: 20px;
  padding-left: 10px;
  position: relative;
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: bold;
  //color: rgba(0, 0, 0, 0.8);
  &::before {
    position: absolute;
    content: "";
    left: 0;
    top: 2px;
    bottom: 2px;
    width: 4px;
    border-radius: 4px;
    background-color: @primary-color;
  }
}
.line-box {
  display: flex;
  align-items: center;
  padding: 10px 0;
  .line-left, .line-right {
    flex: 1;
    height: 1px;
    background: #d7d7d7;
  }
  .line-content {
    width: fit-content;
    padding: 0 4px;
  }
  .line-right {
    position: relative;
  }
  .line-right-del {
    position: absolute;
    right: 0;
    top: -17px;
    background: #fff!important;
    margin-right: 0;
  }
}

:deep(.ant-alert-content) {
  font-size: 12px;
}

:deep(.ant-alert.ant-alert-no-icon) {
  padding: 6px 10px;
}
</style>
